<?php

namespace Frieza\Modules\Vote\Controllers;

use App\Http\Controllers\Controller;
use App\Pockets\GridDataModel as pGridDataModel;
use Doraemon\model\Vote\VoteData;
use Encore\Admin\Facades\Admin;
use Encore\Admin\Grid;
use Encore\Admin\Layout\Content;
use Encore\Admin\Widgets\Form;
use Encore\Admin\Widgets\Tab;
use Illuminate\Http\Request;
use Illuminate\Support\MessageBag;
use Doraemon\tools\BlockType;
use Doraemon\model\Vote\Vote;
use Doraemon\model\Vote\VoteOptions;
use Encore\Admin\Widgets\Table;
use Doraemon\cache\Vote\VoteCounter;


class VoteController extends Controller
{

    const PAGE_SIZE = 20;


    public function index(Request $request, Content $content)
    {
        $params = $request->all();
        $params['page'] = $request->input('page', 1);
        $params['per_page'] = $request->input('per_page', 20);
        if(isset($params['theme'])) {
            $request->merge(['theme'=>$params['theme']]);
        }
        if(isset($params['obj_id'])) {
            $request->merge(['obj_id'=>$params['obj_id']]);
        }

        return $content
            ->header('投票列表')
            ->breadcrumb(
                [
                    'text' => '投票列表',
                    'url'  => '/vote/index'
                ]
            )
            ->body(self::listAction($params));
    }


    private function listAction($params = [])
    {

        $data = Vote::getListForManage($params, 1);
        $votes_data = $data['data'];

        if($votes_data && is_array($votes_data)) {

            $vote_ids = array_column($votes_data, 'id');
            //获取投票项
            $options = VoteOptions::getOptions($vote_ids);
            //获取投票数据
            $datas = VoteData::getDatas($vote_ids);

            $vote_datas = [];
            foreach($options as $vote_id => $option_infos) {
                foreach($option_infos as $option_id => $option_info) {
                    $vote_datas[$vote_id][$option_id] = [
                        "option_id" => $option_info['id'],
                        "option_remark" => $option_info['option_remark'],
                        "num" => (int) $datas['option_counts'][$option_info['id']],
                        "percent" => $datas['option_counts'][$option_info['id']] == 0 ? '0%' : ($datas['option_counts'][$option_info['id']] / $datas['vote_counts'][$vote_id]) * 100 ."%"

                    ];
                }

            }

            foreach($votes_data as &$vote_info) {
                $vote_info['expand'] = $this->_getExpand((array)$vote_datas[$vote_info['id']]);
            }
        }

        $gridModel = new pGridDataModel($votes_data, $data['total'], [
            'perPage' => $params['per_page'],
        ]);


        $listGrid = Admin::grid($gridModel, function (Grid $grid) {
            $grid->disableExport();
            $grid->disableRowSelector();
            $grid->expandFilter();
            $grid->paginate(20);

            $grid->actions(function (Grid\Displayers\Actions $actions){
                $actions->disableDelete();
            });

            // 筛选项
            $grid->filter(function (Grid\Filter $filter) {
                $filter->disableIdFilter();
                $filter->column(1 / 2, function ($filter) {
                    $filter->equal('theme', '投票主题')->placeholder('请输入投票主题关键词');
                });
                $filter->column(1 / 2, function ($filter) {
                    $filter->equal('obj_id', '关联内容ID')->placeholder('请输入内容ID');
                });
            });
            $grid->column('id')->expand(function () {
                return $this->expand;
            }, true)->width(100);
            $grid->column('theme', '投票主题')->width(200)->help('不可以超过15个字符哦');
            $grid->column('show_type', '展示样式')->replace(Vote::STYLE)->width(200);

            $grid->column('source_type', '创建来源')->replace(Vote::ORIGIN);
            $grid->column('obj_id', '投票关联内容');
            $grid->column('addtime', '时间')->display(function() {
                return "创建时间：".$this->addtime."<br/>最后修改时间".$this->edittime;
            });
            $grid->column('admin_id', '最后操作人')->display(function() {
                return Admin::user()->find($this->admin_id)->name;
            });
            $grid->column('extra_text', '投票后展示文案');
            $grid->column('vote_status', '投票状态')->replace(Vote::STATUS);
            $grid->actions(function (Grid\Displayers\Actions $actions) {
                $actions->prepend('<a class="fa reload-data fa-asterisk repair" href="javascript:;" data-id="' .$actions->row->id . '">修复参与人数</a><br><br>');
                $actions->disableDelete();
                $actions->disableView();
                if($actions->row->vote_status != Vote::STATUS_DRAFT) {
                    $actions->disableEdit();
                } else {
                    $actions->prepend('<a class="fa reload-data fa-star online" data-id="' .$actions->row->id . '" href="javascript:;" >操作上线</a><br><br>');
                    $actions->prepend('<a class="fa reload-data fa-cubes" href="/admin/vote/options/' . $actions->row->id . '" >选项管理</a><br><br>');
                }

            });

            Admin::script($this->onlinePopup());
            Admin::script($this->repairPopup());
        });

        return $listGrid;
    }


    private function _getExpand($vote_datas)
    {
        return new Table(['投票项ID', '投票项文案', '投票人数', '投票占比'], array_values($vote_datas));
    }


    //新建/编辑页面
    public function edit(Content $content, $id = 0)
    {
        $tab = new Tab();
        if ($id > 0) {
            $title = '编辑投票';
        } else {
            $title = '创建投票';
        }
        $tab->add("$title", $this->editAction($id));
        return $content
            ->header('投票管理')
            ->breadcrumb(
                [
                    'text' => '投票列表',
                    'url'  => '/vote/index'
                ],
                ['text' => "$title"]
            )
            ->body($tab);
    }

    private function editAction($id = 0)
    {
        if ($id > 0) {
            $data = Vote::getVoteBaseInfo($id);
            $form = new Form($data);
            $form->hidden('id');
        } else {
            $form = new Form();
        }
        $form->text('theme', '投票主题')->required('投票主题必填')->help('15个字符以下');
        $form->radio('show_type', '展示样式')->options(Vote::STYLE)->default(Vote::STYLE_LIST)->help('pk样式仅适用于投票项数量为2时');

        $form->radio('obj_type', '关联内容类型')
            ->options([BlockType::TYPE_PHOTO => 'note', BlockType::TYPE_ARTICLE => '整屋案例', BlockType::TYPE_BLANK => '经验文章', BlockType::TYPE_TOPIC_ACTIVITY => '话题', BlockType::TYPE_GUIDE => '指南'])
            ->when(BlockType::TYPE_PHOTO, function(Form $form) {
                $form->text('obj_id', 'noteID')->help('请填写note_id');
            })->when(BlockType::TYPE_ARTICLE, function(Form $form) {
                $form->text('obj_id', '整屋ID')->help('请填写整屋ID')->readonly();
            })->when(BlockType::TYPE_BLANK, function(Form $form) {
                $form->text('obj_id', '经验文章ID')->help('请填写经验文章id')->readonly();
            })->when(BlockType::TYPE_TOPIC_ACTIVITY, function(Form $form) {
                $form->text('obj_id', '话题ID')->help('请填写话题id')->readonly();
            })->when(BlockType::TYPE_GUIDE, function(Form $form) {
                $form->text('obj_id', '指南ID')->help('请填写指南id')->readonly();
            })->default(BlockType::TYPE_PHOTO)->help('目前仅支持关联至note');

        $form->text('extra_text', '投票后展示文案')->help('不填使用默认文案');

        $form->action('/admin/vote/index/save');

        return $form;
    }

    public function saveSubmit(Request $request)
    {
        $params = $request->all();
        $data = [
            'theme' => $params['theme'],
            'show_type' => $params['show_type'],
            'obj_type' => $params['obj_type'],
            'obj_id' => $params['obj_id'],
            'source_type' => Vote::ORIGIN_MANAGE,
            'vote_status' => Vote::STATUS_DRAFT,
            'admin_id' => Admin::user()->id,
            'extra_text' => $params['extra_text']
        ];
        //校验投票主题字数
        if(mb_strlen($params['extra_text']) > 15) {
            $error = new MessageBag([
                'title' => '保存失败,投票后提示文案不可以超过15个字符哦'
            ]);
            return back()->with(compact('error'));
        }
        if(mb_strlen($params['theme']) > 15) {
            $error = new MessageBag([
                'title' => '保存失败,投票主题不可以超过15个字符哦'
            ]);
            return back()->with(compact('error'));
        }
        if(isset($params['id']) && $params['id']) {
            //编辑
            $data['edittime'] = date('Y-m-d H:i:s', time());
            $rs = Vote::editData($params['id'], $data);

        } else {
            //创建
            $data['addtime'] = date('Y-m-d H:i:s', time());
            $rs = Vote::addData($data);
        }
        if ($rs) {
            $success = new MessageBag([
                'title' => '保存成功,可以去设置投票项啦'
            ]);
            return redirect('/admin/vote/index')->with(compact('success'));

        } else {
            $error = new MessageBag([
                'title' => '保存失败'
            ]);
            return back()->with(compact('error'));
        }
    }

    //选项列表
    public function optionList(Content $content, $id)
    {
        $vote_info = Vote::getVoteBaseInfo($id);
        $theme = '';
        if(isset($vote_info['theme']) && $vote_info['theme']) {
            $theme = $vote_info['theme'];
        }
        return $content
            ->header('投票 ╓'.$theme.'╜ 投票项列表'."<span style='font-size: 12px;'> (投票项不可以超过15个字符，pk样式的投票项不可以超过5个字符)</span>")
            ->breadcrumb(
                [
                    'text' => '投票列表',
                    'url'  => '/vote/index'
                ],
                [
                    'text' => '投票项列表',
                    'url'  => '/vote/optionlist'
                ]
            )
            ->body(self::optionListAction($id));
    }

    private static function optionListAction($id = 0)
    {

        $data = VoteOptions::getOptionListForManage($id);

        $votes_data = $data['data'];
        $gridModel = new pGridDataModel($votes_data, $data['total']);


        $listGrid = Admin::grid($gridModel, function (Grid $grid) {
            $grid->disableExport();
            $grid->disableRowSelector();
            $grid->expandFilter();
            $grid->disablePagination();
            $grid->disableFilter();
            $grid->disableCreateButton();

            $grid->quickCreate(function (Grid\Tools\QuickCreate $create) {
                $create->text('option_remark', '投票项');
            });

            $grid->column('id')->sort();
            $grid->column('option_remark', '投票项文案')->editable()->width(400)->help('不可以超过15个字符哦');
            $grid->column('option_sort', '投票项排序')->width(200);

            $grid->column('addtime', '时间')->display(function() {
                return "创建时间：".$this->addtime."<br/>最后自改时间".$this->edittime;
            });
            $grid->column('admin_id', '最后操作人')->display(function() {
                return Admin::user()->find($this->admin_id)->name;
            });

            $grid->actions(function (Grid\Displayers\Actions $actions) {
                $actions->disableEdit();

            });

        });

        return $listGrid;
    }

    //选项提交
    public function optionSaveSubmit(Request $request, $vote_id, $option_id = 0)
    {
        try {
            $request = $request->all();
            $vote_info = Vote::getVoteBaseInfo($vote_id);
            if(isset($vote_info['vote_status']) && $vote_info['vote_status'] == Vote::STATUS_NORMAL) {
                throw new \Exception('操作失败,已上线的投票不允许添加/修改投票项');
            }
            $data = [
                "vote_id" => $vote_id,
                "admin_id" => Admin::user()->id,
                "option_status" => VoteOptions::STATUS_NORMAL
            ];

            if(mb_strlen($request['value']) > 15 || mb_strlen($request['option_remark']) > 15) {
                throw new \Exception('保存失败,投票项不可以超过15个字符哦');
            }

            if($vote_info['show_type'] == Vote::STYLE_PK && (mb_strlen($request['value']) > 5 || mb_strlen($request['option_remark']) > 5)) {
                throw new \Exception('保存失败,pk样式的投票项不可以超过5个字符哦');
            }

            if(mb_strlen($request['value']) < 1 && mb_strlen($request['option_remark']) < 1) {
                throw new \Exception('保存失败,投票项不可以为空哦');
            }

            //限制选项必须不同
            $remark = $request['option_remark'] ? : $request['value'];
            $has_option_info = VoteOptions::get('*', ['option_status' => VoteOptions::STATUS_NORMAL, 'vote_id' => $vote_id, 'option_remark' => $remark]);
            if($has_option_info && is_array($has_option_info) && $has_option_info['id'] != $option_id) {
                throw new \Exception('保存失败,投票项不可以重复');
            }

            if(isset($option_id) && $option_id) {
                //修改
                $data["option_remark"] = $request['value'];
                $data['edittime'] = date('Y-m-d H:i:s', time());
                $rs = VoteOptions::editData($option_id, $data);
            } else {
                //添加
                $data["option_remark"] = $request['option_remark'];
                $data['addtime'] = date('Y-m-d H:i:s', time());
                $rs = VoteOptions::addData($data);
            }

            if($rs) {
                return response()->json([
                    'status' => true,
                    'message' => "操作成功",
                ]);
            } else {
                throw new \Exception('保存失败,请联系研发');
            }
        } catch (\Exception $e) {
            return response()->json(['message' => $message = $e->getMessage()], 422);
        };


    }

    //选项排序
    public function sortOption(Request $request)
    {
        $request = $request->all();
        $sort_arr = $request['sort'];
        if($sort_arr && is_array($sort_arr)) {
            foreach($sort_arr as $option_id => $sort) {
                VoteOptions::editData($option_id, [
                    "edittime" => date('Y-m-d H:i:s', time()),
                    "option_sort" => $sort,
                    "admin_id" => Admin::user()->id
                ]);
            }
        }
    }

    //删除投票项
    public function delOption($vote_id, $option_id)
    {

        $vote_info = Vote::getVoteBaseInfo($vote_id);
        if(isset($vote_info['vote_status']) && $vote_info['vote_status'] == Vote::STATUS_NORMAL) {
            return response()->json([
                'status' => false,
                'message' => "删除失败,已上线的投票不允许删除投票项",
            ]);
        }

        $rs = VoteOptions::editData($option_id, [
            "edittime" => date('Y-m-d H:i:s', time()),
            "option_status" => VoteOptions::STATUS_DELETE_ADMIN,
            "admin_id" => Admin::user()->id
        ]);

        if($rs) {
            return response()->json([
                'status' => true,
                'message' => "删除成功",
            ]);
        } else {
            return response()->json([
                'status' => false,
                'message' => "删除失败",
            ]);
        }

    }


    //上线弹窗
    public function onlinePopup()
    {
        return <<<SCRIPT
           
            $('.online').unbind('click').click(function() {
            var id = $(this).data('id');
            swal({
                title: "确认要将这个投票上线吗？上线后投票内容将不可修改！",
                type: "warning",
                showCancelButton: true,
                confirmButtonColor: "#DD6B55",
                confirmButtonText: "确认上线",
                showLoaderOnConfirm: true,
                cancelButtonText: "取消",
                preConfirm: function() {
                    $.post('online', {'id':id}, function (data) {
                        $.pjax.reload('#pjax-container');
                        if(data.code == 1) {
                            swal(data.msg, '', 'success');
                        } else {
                            swal(data.msg, '', 'error');
                        }
                    });
                   
                }
            });
        });
SCRIPT;
    }

    //投票操作上线
    public function online(Request $request)
    {
        $request = $request->all();
        $vote_id = $request['id'];
        //校验选项数量
        $vote_info = Vote::getVoteBaseInfo($vote_id);
        $show_type = (int) $vote_info['show_type'];
        $option_num = (int) VoteOptions::getOptionListForManage($vote_id)['total'];
        if($show_type == Vote::STYLE_PK && $option_num != 2) {
            return response()->json([
                'code' => 0,
                'msg' => "pk样式下的投票必须仅拥有两个投票项",
            ]);
        }

        if($option_num < 2) {
            return response()->json([
                'code' => 0,
                'msg' => "投票项至少有两个哦，快去配投票项吧",
            ]);
        } else if ($option_num > 10) {
            return response()->json([
                'code' => 0,
                'msg' => "投票项最多只能有十个哦",
            ]);
        }

        //投票项字数校验
        $options = VoteOptions::getOptionListForManage($vote_id)['data'];
        if($options && is_array($options)) {
            foreach($options as $option_info) {
                if($show_type == Vote::STYLE_PK) {
                    if(mb_strlen($option_info['option_remark']) > 5) {
                        return response()->json([
                            'code' => 0,
                            'msg' => "px样式的投票项不可以超过5个字符哦",
                        ]);
                    }
                } else {
                    if(mb_strlen($option_info['option_remark']) > 15) {
                        return response()->json([
                            'code' => 0,
                            'msg' => "投票项不可以超过15个字符哦",
                        ]);
                    }
                }
            }
        }

        //校验内容是否已绑定投票
        $rs = Vote::get('*', [
            'vote_status' => Vote::STATUS_NORMAL,
            'obj_id' => $vote_info['obj_id']
        ]);
        if($rs && is_array($rs)) {
            return response()->json([
                'code' => 0,
                'msg' => '关联内容已绑定其他投票，请重新选择关联内容',
            ]);
        }

        if(empty($vote_info['obj_id'])) {
            return response()->json([
                'code' => 0,
                'msg' => '关联内容后才能上线投票哦，请先关联内容',
            ]);
        }

        $result = Vote::editData($vote_id, [
            'vote_status' => Vote::STATUS_NORMAL,
            'edittime' => date('Y-m-d H:i:s', time()),
            'admin_id' => Admin::user()->id
        ]);

        if($result) {
            return response()->json([
                'code' => 1,
                'msg' => '上线成功',
            ]);
        } else {
            return response()->json([
                'code' => 0,
                'msg' => '上线失败',
            ]);
        }

    }

    //计数器修复弹窗
    public function repairPopup()
    {
        return <<<SCRIPT
           
            $('.repair').unbind('click').click(function() {
            var id = $(this).data('id');
            swal({
                title: "修复后可能会影响app中展示的投票票数，确认修复嘛？",
                type: "warning",
                showCancelButton: true,
                confirmButtonColor: "#DD6B55",
                confirmButtonText: "确认修复",
                showLoaderOnConfirm: true,
                cancelButtonText: "取消",
                preConfirm: function() {
                    $.post('repair', {'id':id}, function (data) {
                        $.pjax.reload('#pjax-container');
                        if(data.code == 1) {
                            swal(data.msg, '', 'success');
                        } else {
                            swal(data.msg, '', 'error');
                        }
                    });
                   
                }
            });
        });
SCRIPT;
    }

    //投票计数器修复
    public function repair(Request $request)
    {
        $request = $request->all();
        $voteId = $request['id'];
        $options = VoteOptions::getOptionList($voteId);

        $counts = VoteData::getData($voteId);

        if($options && is_array($options)) {
            foreach($options as $optionInfo) {
                VoteCounter::setCounterByVoteId($voteId, $optionInfo['id'], (int) $counts[$optionInfo['id']]);
            }
        }
        return response()->json([
            'code' => 1,
            'msg' => '修复成功'
        ]);

    }


}
